﻿namespace Library.Navigation
{
    using System;
    using System.Net;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.Generic;
    using Library.Storage;

    public class NavigationHistoryStorageProvider : INavigationHistoryStorageProvider
    {
        private const string NavigationStackStorageKey = "NavigationProviderStack";

        private const string KnownTypesStorageKey = "NavigationProviderStackKnownTypes";

        public List<NavigationEntry> RestoreHistory()
        {
            var result = new List<NavigationEntry>();
           
            var storageProvider = new StorageProvider();
            var typesSerializer = new JsonSerializer();
            var knownTypeNames = storageProvider.ReadFromFile<List<string>>(KnownTypesStorageKey, typesSerializer);

            if (knownTypeNames != null)
            {
                var serializer = new JsonSerializer();
                foreach (var typeName in knownTypeNames)
                {
                    var type = Type.GetType(typeName);
                    serializer.KnownTypes.Add(type);
                }

                var storedHistory = storageProvider.ReadFromFile<List<NavigationEntry>>(NavigationStackStorageKey, serializer);
                if (storedHistory != null)
                {
                    result = storedHistory;
                }
            }

            return result;
        }

        public void StoreHistory(List<NavigationEntry> navigationStack)
        {
            var serializer = new JsonSerializer();
            var storageProvider = new StorageProvider();
            var knownTypes = new List<Type>();
            foreach (var item in navigationStack)
            {
                this.AddToKnownTypes(serializer.KnownTypes, item.Source);
                this.AddToKnownTypes(serializer.KnownTypes, item.Parameter);
            }

            storageProvider.WriteToFile(NavigationStackStorageKey, navigationStack, serializer);

            var storedTypes = serializer.KnownTypes.Select(t => t.AssemblyQualifiedName).ToArray();
            var typesSerializer = new JsonSerializer();
            storageProvider.WriteToFile(KnownTypesStorageKey, storedTypes, typesSerializer);
        }

        private void AddToKnownTypes(List<Type> knownTypes, object checkedValue)
        {
            if (checkedValue != null)
            {
                var type = checkedValue.GetType();
                var typeAlreadyExisted = knownTypes.Contains(type);
                if (!typeAlreadyExisted)
                {
                    knownTypes.Add(type);
                }
            }
        }
    }
}
